#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

// MESI协议状态定义
typedef enum { 
    MODIFIED,      // 已修改状态 - 缓存中的数据已被修改，与主存不一致
    EXCLUSIVE,     // 独占状态   - 缓存中数据未被修改，且仅此缓存有该数据
    SHARED,        // 共享状态   - 缓存中数据未被修改，其他缓存可能有该数据
    INVALID        // 无效状态   - 缓存行无效
} CacheState;

// 缓存行结构体
typedef struct {
    int tag;           // 内存地址标签
    CacheState state;  // 当前状态
    int data;          // 缓存的数据
} CacheLine;

// CPU核结构体
typedef struct {
    CacheLine L1[2];   // L1缓存 - 2个缓存行
} CPU;

CPU cores[2];         // 两个CPU核的L1缓存
int memory = 0;        // 全局内存（共享）

// 状态到字符串的转换
const char* state_to_string(CacheState state) {
    switch (state) {
        case MODIFIED:  return "MODIFIED";
        case EXCLUSIVE: return "EXCLUSIVE";
        case SHARED:    return "SHARED";
        case INVALID:   return "INVALID";
        default:        return "UNKNOWN";
    }
}

// 初始化缓存系统
void init_cache() {
    // 内存初始值
    memory = 0;
    
    // 初始化所有缓存行为无效状态
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            cores[i].L1[j].state = INVALID;
            cores[i].L1[j].tag = -1;
            cores[i].L1[j].data = 0;
        }
    }
    
    printf("缓存系统已初始化\n");
}

// 处理LOAD操作
void handle_load(int core_id, int address) {
    int index = address % 2;  // 简化索引计算
    CacheLine *line = &cores[core_id].L1[index];
    
    if (line->state == INVALID) {
        // 检查其他核心是否持有相同数据
        bool other_has_copy = false;
        for (int i = 0; i < 2; i++) {
            if (i != core_id) {
                CacheLine *other_line = &cores[i].L1[index];
                if (other_line->state != INVALID && other_line->tag == address) {
                    other_has_copy = true;
                    // 更新其他缓存状态为SHARED
                    if (other_line->state != SHARED) {
                        other_line->state = SHARED;
                        printf("Core %d: X状态更新为SHARED\n", i);
                    }
                }
            }
        }
        
        // 设置当前缓存状态
        line->state = other_has_copy ? SHARED : EXCLUSIVE;
        line->tag = address;
        line->data = memory;  // 从内存加载数据
        
        printf("Core %d: LOAD X → 状态: %s\n", 
               core_id, state_to_string(line->state));
    } else {
        // 缓存命中，直接返回
        printf("Core %d: LOAD X (缓存命中) → 状态: %s\n", 
               core_id, state_to_string(line->state));
    }
}

// 处理STORE操作
void handle_store(int core_id, int address) {
    int index = address % 2;
    CacheLine *line = &cores[core_id].L1[index];
    
    if (line->state == SHARED || line->state == EXCLUSIVE) {
        // 广播无效化信号
        for (int i = 0; i < 2; i++) {
            if (i != core_id) {
                CacheLine *other_line = &cores[i].L1[index];
                if (other_line->state != INVALID && other_line->tag == address) {
                    other_line->state = INVALID;
                    printf("Core %d: X无效化\n", i);
                }
            }
        }
        
        line->state = MODIFIED;
        line->data++;  // 修改数据
        memory = line->data;  // 写回内存
        
        printf("Core %d: STORE X → 状态: MODIFIED\n", core_id);
    } else if (line->state == MODIFIED) {
        // 已在修改状态，直接更新
        line->data++;
        memory = line->data;
        
        printf("Core %d: STORE X (已在MODIFIED状态)\n", core_id);
    } else { // INVALID状态
        // 加载数据到缓存
        line->tag = address;
        line->state = MODIFIED;
        line->data = memory + 1;  // 加载并修改
        memory = line->data;
        
        // 其他核心无效化
        for (int i = 0; i < 2; i++) {
            if (i != core_id) {
                CacheLine *other_line = &cores[i].L1[index];
                if (other_line->tag == address) {
                    other_line->state = INVALID;
                    printf("Core %d: X无效化\n", i);
                }
            }
        }
        
        printf("Core %d: STORE X → 状态: MODIFIED (从内存加载)\n", core_id);
    }
}

// 打印缓存状态
void print_cache_state(int core_id) {
    printf("Core %d缓存状态:\n", core_id);
    for (int i = 0; i < 2; i++) {
        CacheLine *line = &cores[core_id].L1[i];
        printf("  缓存行 %d: 标签=%d, 状态=%s, 数据=%d\n", 
               i, line->tag, state_to_string(line->state), line->data);
    }
}

// 打印系统整体状态
void print_system_state() {
    printf("\n====== 系统当前状态 ======\n");
    printf("内存值: %d\n", memory);
    for (int i = 0; i < 2; i++) {
        print_cache_state(i);
    }
    printf("=========================\n\n");
}

// 简化的命令解释器
void process_command(const char* input) {
    if (strcmp(input, "exit") == 0) {
        exit(0);
    }
    else if (strcmp(input, "state") == 0) {
        print_system_state();
    }
    else if (strncmp(input, "Core", 4) == 0) {
        int core_id = 0;
        char op[10];
        char variable;
        
        if (sscanf(input, "Core %d: %s %c", &core_id, op, &variable) == 3) {
            if (core_id < 0 || core_id > 1) {
                printf("错误: 核心ID必须是0或1\n");
                return;
            }
            
            if (variable != 'X') {
                printf("警告: 仅支持变量X的操作, 使用X继续\n");
            }
            
            if (strcmp(op, "LOAD") == 0) {
                handle_load(core_id, 0);
            }
            else if (strcmp(op, "STORE") == 0) {
                handle_store(core_id, 0);
            }
            else {
                printf("错误: 未知操作 '%s'\n", op);
            }
            
            // 显示操作后状态
            printf("操作后系统状态:\n");
            printf("---------------------------------------\n");
            printf("Core %d: X状态 = %s\n", core_id, state_to_string(cores[core_id].L1[0].state));
            printf("内存值 = %d\n", memory);
            printf("---------------------------------------\n\n");
        }
        else {
            printf("错误: 无效命令格式. 请使用: Core 0: LOAD X\n");
        }
    }
    else {
        printf("错误: 未知命令 '%s'\n", input);
    }
}

int main() {
    init_cache();
    
    printf("==== 两级缓存一致性模拟器 ====\n");
    printf("支持命令:\n");
    printf("  Core [0|1]: LOAD [X]\n");
    printf("  Core [0|1]: STORE [X]\n");
    printf("  state      - 显示当前状态\n");
    printf("  exit       - 退出程序\n");
    printf("==============================\n\n");
    
    char input[100];
    
    while (1) {
        printf("> ");
        fflush(stdout);  // 确保输出被刷新
        
        if (fgets(input, sizeof(input), stdin) == NULL) {
            break; // 处理Ctrl+D (Unix)或Ctrl+Z (Windows)
        }
        
        // 去除换行符
        input[strcspn(input, "\n")] = '\0';
        
        // 处理命令
        process_command(input);
    }
    
    return 0;
}
